package com.small.xx.ai.file.controller;

import com.small.xx.ai.file.dto.DirectoryBrowseRequest;
import com.small.xx.ai.file.dto.DirectoryBrowseResponse;
import com.small.xx.ai.file.dto.FileUploadRequest;
import com.small.xx.ai.file.dto.FileUploadResponse;
import com.small.xx.ai.file.dto.MultiFileUploadResponse;
import com.small.xx.ai.file.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

// 添加生成二维码所需的导入
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件目录控制器
 * 提供文件目录浏览的Web接口
 * 
 * @author xx-ai
 * @version 1.0.0
 */
@Controller
@RequestMapping("/file")
public class FileController {

    @Autowired
    private FileService fileService;

    /**
     * 获取服务器IP地址信息
     * 
     * @param request HTTP请求对象
     * @return IP地址信息
     */
    @GetMapping("/api/ip-addresses")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> getIpAddresses(HttpServletRequest request) {
        try {
            Map<String, Object> result = new HashMap<>();
            
            // 获取服务器地址和端口
            String scheme = request.getScheme();
            String serverName = request.getServerName();
            int serverPort = request.getServerPort();
            String contextPath = request.getContextPath();
            
            // 构建基础URL
            String baseUrl;
            if (serverPort == 80 || serverPort == 443) {
                baseUrl = String.format("%s://%s%s/file/", scheme, serverName, contextPath);
            } else {
                baseUrl = String.format("%s://%s:%d%s/file/", scheme, serverName, serverPort, contextPath);
            }
            
            // 获取本机所有网络接口的IP地址
            java.util.List<String> localIps = new java.util.ArrayList<>();
            try {
                java.net.InetAddress localHost = java.net.InetAddress.getLocalHost();
                localIps.add(localHost.getHostAddress());
                
                // 获取所有网络接口的IP地址
                java.util.Enumeration<java.net.NetworkInterface> networkInterfaces = 
                    java.net.NetworkInterface.getNetworkInterfaces();
                
                while (networkInterfaces.hasMoreElements()) {
                    java.net.NetworkInterface networkInterface = networkInterfaces.nextElement();
                    java.util.Enumeration<java.net.InetAddress> addresses = networkInterface.getInetAddresses();
                    
                    while (addresses.hasMoreElements()) {
                        java.net.InetAddress address = addresses.nextElement();
                        // 只获取IPv4地址，排除回环地址
                        if (address instanceof java.net.Inet4Address && 
                            !address.isLoopbackAddress() && 
                            !address.getHostAddress().startsWith("127.")) {
                            localIps.add(address.getHostAddress());
                        }
                    }
                }
            } catch (Exception e) {
                // 如果获取本地IP失败，至少添加回环地址
                localIps.add("127.0.0.1");
                localIps.add("::1");
            }
            
            // 去重
            java.util.Set<String> uniqueIps = new java.util.HashSet<>(localIps);
            localIps = new java.util.ArrayList<>(uniqueIps);
            
            // 构建地址列表
            java.util.List<Map<String, String>> addresses = new java.util.ArrayList<>();
            
            // 添加回环地址
            Map<String, String> loopbackV4 = new HashMap<>();
            loopbackV4.put("name", "本地回环地址");
            loopbackV4.put("url", String.format("%s://%s%s/file/", scheme, "127.0.0.1", 
                serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort));
            loopbackV4.put("type", "IPv4");
            addresses.add(loopbackV4);
            
            Map<String, String> loopbackV6 = new HashMap<>();
            loopbackV6.put("name", "本地回环地址");
            loopbackV6.put("url", String.format("%s://%s%s/file/", scheme, "[::1]", 
                serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort));
            loopbackV6.put("type", "IPv6");
            addresses.add(loopbackV6);
            
            // 添加本地IP地址
            for (String ip : localIps) {
                if (!"127.0.0.1".equals(ip) && !"::1".equals(ip)) {
                    Map<String, String> addr = new HashMap<>();
                    addr.put("name", "本地IP地址");
                    addr.put("url", String.format("%s://%s%s/file/", scheme, ip, 
                        serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort));
                    addr.put("type", ip.contains(":") ? "IPv6" : "IPv4");
                    addresses.add(addr);
                }
            }
            
            result.put("success", true);
            result.put("addresses", addresses);
            result.put("baseUrl", baseUrl);
            
            return ResponseEntity.ok(result);
            
        } catch (Exception e) {
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("success", false);
            errorResult.put("message", "获取IP地址信息失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResult);
        }
    }

    /**
     * 显示文件浏览器主页
     * 
     * @param model 模型对象
     * @return 主页模板
     */
    @GetMapping("/")
    public String index(Model model) {
        // 设置默认路径为用户主目录
        String defaultPath = System.getProperty("user.home");
        model.addAttribute("defaultPath", defaultPath);
        return "file/index";
    }

    /**
     * 显示目录浏览页面
     * 
     * @param path 目录路径
     * @param showHidden 是否显示隐藏文件
     * @param sortBy 排序字段
     * @param sortOrder 排序顺序
     * @param model 模型对象
     * @return 目录浏览模板
     */
    @GetMapping("/browse")
    public String browse(
            @RequestParam(value = "path", required = false) String path,
            @RequestParam(value = "showHidden", defaultValue = "false") Boolean showHidden,
            @RequestParam(value = "sortBy", defaultValue = "") String sortBy,
            @RequestParam(value = "sortOrder", defaultValue = "") String sortOrder,
            Model model) {

        try {
            // 如果没有指定路径，使用用户主目录
            if (path == null || path.trim().isEmpty()) {
                path = System.getProperty("user.home");
            } else {
                // URL解码路径参数
                try {
                    path = URLDecoder.decode(path, StandardCharsets.UTF_8);
                    System.out.println("解码后的路径: " + path);
                } catch (Exception e) {
                    System.err.println("路径解码失败: " + e.getMessage());
                    // 如果解码失败，使用原始路径
                }
            }

            // 检查路径安全性
            if (!fileService.isPathSafe(path)) {
                model.addAttribute("error", "不安全的路径: " + path);
                model.addAttribute("currentPath", "");
                return "file/browse";
            }

            // 创建请求对象
            DirectoryBrowseRequest request = new DirectoryBrowseRequest();
            request.setPath(path);
            request.setShowHidden(showHidden);
            request.setSortBy(sortBy);
            request.setSortOrder(sortOrder);

            // 获取目录内容
            DirectoryBrowseResponse response = fileService.browseDirectory(request);

            // 检查响应是否有效
            if (response == null) {
                model.addAttribute("error", "获取目录信息失败");
                model.addAttribute("currentPath", path);
                return "file/browse";
            }

            // 添加到模型
            model.addAttribute("response", response);
            model.addAttribute("currentPath", response.getCurrentPath() != null ? response.getCurrentPath() : path);
            model.addAttribute("showHidden", showHidden);
            model.addAttribute("sortBy", sortBy);
            model.addAttribute("sortOrder", sortOrder);
            model.addAttribute("fileService", fileService);

            return "file/browse";
            
        } catch (Exception e) {
            // 记录详细错误信息
            System.err.println("Browse error: " + e.getMessage());
            e.printStackTrace();
            
            model.addAttribute("error", "浏览目录时发生错误: " + e.getMessage());
            model.addAttribute("currentPath", path != null ? path : "");
            model.addAttribute("response", null);
            model.addAttribute("showHidden", showHidden);
            model.addAttribute("sortBy", sortBy);
            model.addAttribute("sortOrder", sortOrder);
            model.addAttribute("fileService", fileService);
            
            return "file/browse";
        }
    }

    /**
     * REST API - 浏览目录
     * 
     * @param request 目录浏览请求
     * @return 目录浏览响应
     */
    @PostMapping("/api/browse")
    @ResponseBody
    public ResponseEntity<DirectoryBrowseResponse> browseDirApi(@RequestBody DirectoryBrowseRequest request) {
        // 检查路径安全性
        if (!fileService.isPathSafe(request.getPath())) {
            DirectoryBrowseResponse errorResponse = new DirectoryBrowseResponse();
            errorResponse.setAccessible(false);
            errorResponse.setErrorMessage("不安全的路径: " + request.getPath());
            return ResponseEntity.badRequest().body(errorResponse);
        }

        DirectoryBrowseResponse response = fileService.browseDirectory(request);
        
        if (response.getAccessible()) {
            return ResponseEntity.ok(response);
        } else {
            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * REST API - 获取目录内容（GET方式）
     * 
     * @param path 目录路径
     * @param showHidden 是否显示隐藏文件
     * @param sortBy 排序字段
     * @param sortOrder 排序顺序
     * @return 目录浏览响应
     */
    @GetMapping("/api/browse")
    @ResponseBody
    public ResponseEntity<DirectoryBrowseResponse> browseDirApiGet(
            @RequestParam("path") String path,
            @RequestParam(value = "showHidden", defaultValue = "false") Boolean showHidden,
            @RequestParam(value = "sortBy", defaultValue = "") String sortBy,
            @RequestParam(value = "sortOrder", defaultValue = "") String sortOrder) {

        // URL解码路径参数
        try {
            path = URLDecoder.decode(path, StandardCharsets.UTF_8);
            System.out.println("API解码后的路径: " + path);
        } catch (Exception e) {
            System.err.println("API路径解码失败: " + e.getMessage());
        }
        
        // 检查路径安全性
        if (!fileService.isPathSafe(path)) {
            DirectoryBrowseResponse errorResponse = new DirectoryBrowseResponse();
            errorResponse.setAccessible(false);
            errorResponse.setErrorMessage("不安全的路径: " + path);
            return ResponseEntity.badRequest().body(errorResponse);
        }

        DirectoryBrowseRequest request = new DirectoryBrowseRequest();
        request.setPath(path);
        request.setShowHidden(showHidden);
        request.setSortBy(sortBy);
        request.setSortOrder(sortOrder);

        DirectoryBrowseResponse response = fileService.browseDirectory(request);
        
        if (response.getAccessible()) {
            return ResponseEntity.ok(response);
        } else {
            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 处理错误页面
     * 
     * @param model 模型对象
     * @return 错误页面模板
     */
    @GetMapping("/error")
    public String error(Model model) {
        model.addAttribute("error", "访问文件时发生错误");
        return "file/error";
    }

    // ================ 文件上传下载功能 ================

    /**
     * 显示文件上传页面
     * 
     * @param path 目标目录路径
     * @param model 模型对象
     * @return 上传页面模板
     */
    @GetMapping("/upload")
    public String uploadPage(
            @RequestParam(value = "path", required = false) String path,
            Model model) {
        
        // 如果没有指定路径，使用用户主目录
        if (path == null || path.trim().isEmpty()) {
            path = System.getProperty("user.home");
        }
        
        model.addAttribute("targetPath", path);
        return "file/upload";
    }

    /**
     * 显示上传结果页面（处理直接访问）
     * 
     * @param model 模型对象
     * @return 上传结果页面模板
     */
    @GetMapping("/upload-result")
    public String uploadResultPage(Model model) {
        // 设置默认属性，防止直接访问时出现null值错误
        model.addAttribute("targetPath", System.getProperty("user.home"));
        model.addAttribute("totalFiles", 0);
        model.addAttribute("successCount", 0);
        model.addAttribute("failCount", 0);
        model.addAttribute("successFiles", new ArrayList<>());
        model.addAttribute("failedFiles", new ArrayList<>());
        model.addAttribute("error", "没有上传数据，请先进行文件上传");
        
        // 添加简化模板表达式的属性
        model.addAttribute("hasTotalFiles", false);
        model.addAttribute("hasSuccessFiles", false);
        model.addAttribute("hasFailedFiles", false);
        model.addAttribute("allSuccess", false);
        
        // 设置默认的成功率和失败率
        model.addAttribute("successRate", "0%");
        model.addAttribute("successRateWidth", "0%");
        model.addAttribute("failRateWidth", "0%");
        
        return "file/upload-result";
    }

    /**
     * 处理文件上传（支持多文件）
     * 
     * @param files 上传的文件数组
     * @param targetPath 目标路径
     * @param overwrite 是否覆盖同名文件
     * @param description 文件描述
     * @param uploader 上传者
     * @param showDetail 是否显示详细结果页面
     * @param redirectAttributes 重定向属性
     * @param model 模型对象
     * @return 重定向到目录浏览页面或显示详细结果页面
     */
    @PostMapping("/upload")
    public String uploadFiles(
            @RequestParam("file") MultipartFile[] files,
            @RequestParam("targetPath") String targetPath,
            @RequestParam(value = "overwrite", defaultValue = "false") Boolean overwrite,
            @RequestParam(value = "description", required = false) String description,
            @RequestParam(value = "uploader", required = false) String uploader,
            @RequestParam(value = "showDetail", defaultValue = "false") Boolean showDetail,
            RedirectAttributes redirectAttributes,
            Model model) {
        
        try {
            // 验证文件数组
            if (files == null || files.length == 0) {
                if (showDetail) {
                    model.addAttribute("targetPath", targetPath);
                    model.addAttribute("totalFiles", 0);
                    model.addAttribute("successCount", 0);
                    model.addAttribute("failCount", 0);
                    model.addAttribute("successFiles", new ArrayList<>());
                    model.addAttribute("failedFiles", new ArrayList<>());
                    model.addAttribute("error", "请选择要上传的文件");
                    return "file/upload-result";
                }
                redirectAttributes.addFlashAttribute("error", "请选择要上传的文件");
                return "redirect:/file/browse?path=" + URLEncoder.encode(targetPath, StandardCharsets.UTF_8);
            }
            
            // 检查是否有空文件
            for (MultipartFile file : files) {
                if (file.isEmpty()) {
                    if (showDetail) {
                        model.addAttribute("targetPath", targetPath);
                        model.addAttribute("totalFiles", files.length);
                        model.addAttribute("successCount", 0);
                        model.addAttribute("failCount", files.length);
                        model.addAttribute("successFiles", new ArrayList<>());
                        model.addAttribute("failedFiles", new ArrayList<>());
                        model.addAttribute("error", "检测到空文件，请重新选择");
                        return "file/upload-result";
                    }
                    redirectAttributes.addFlashAttribute("error", "检测到空文件，请重新选择");
                    return "redirect:/file/browse?path=" + URLEncoder.encode(targetPath, StandardCharsets.UTF_8);
                }
            }
            
            // 创建上传请求对象
            FileUploadRequest request = new FileUploadRequest();
            request.setTargetPath(targetPath);
            request.setOverwrite(overwrite);
            request.setDescription(description);
            request.setUploader(uploader);

            // 执行多文件上传
            List<FileUploadResponse> responses = fileService.uploadFiles(files, request);
            
            // 统计上传结果
            List<FileUploadResponse> successFiles = new ArrayList<>();
            List<FileUploadResponse> failedFiles = new ArrayList<>();
            
            for (FileUploadResponse response : responses) {
                if (response.getSuccess()) {
                    successFiles.add(response);
                } else {
                    failedFiles.add(response);
                }
            }
            
            // 如果需要显示详细结果页面
            if (showDetail || failedFiles.size() > 0) {
                model.addAttribute("targetPath", targetPath);
                model.addAttribute("totalFiles", responses.size());
                model.addAttribute("successCount", successFiles.size());
                model.addAttribute("failCount", failedFiles.size());
                model.addAttribute("successFiles", successFiles);
                model.addAttribute("failedFiles", failedFiles);
                
                // 添加简化模板表达式的属性
                model.addAttribute("hasTotalFiles", responses.size() > 0);
                model.addAttribute("hasSuccessFiles", successFiles.size() > 0);
                model.addAttribute("hasFailedFiles", failedFiles.size() > 0);
                model.addAttribute("allSuccess", responses.size() > 0 && responses.size() == successFiles.size());
                
                // 计算成功率
                if (responses.size() > 0) {
                    double successRate = (double) successFiles.size() / responses.size() * 100;
                    model.addAttribute("successRate", String.format("%.1f", successRate) + "%");
                    model.addAttribute("successRateWidth", String.format("%.1f", successRate) + "%");
                } else {
                    model.addAttribute("successRate", "0%");
                    model.addAttribute("successRateWidth", "0%");
                }
                
                // 计算失败率
                if (responses.size() > 0) {
                    double failRate = (double) failedFiles.size() / responses.size() * 100;
                    model.addAttribute("failRateWidth", String.format("%.1f", failRate) + "%");
                } else {
                    model.addAttribute("failRateWidth", "0%");
                }
                
                return "file/upload-result";
            }
            
            // 设置简单的反馈消息
            if (!successFiles.isEmpty()) {
                String successMessage = String.format("成功上传 %d 个文件", successFiles.size());
                redirectAttributes.addFlashAttribute("success", successMessage);
            }
            
            if (!failedFiles.isEmpty()) {
                List<String> errorMessages = new ArrayList<>();
                for (FileUploadResponse response : failedFiles) {
                    errorMessages.add(response.getFileName() + ": " + response.getMessage());
                }
                String errorMessage = String.format("上传失败 %d 个文件: %s", 
                    failedFiles.size(), String.join("; ", errorMessages));
                redirectAttributes.addFlashAttribute("error", errorMessage);
            }

        } catch (Exception e) {
            // 如果需要显示详细结果页面，即使发生异常也要设置相关属性
            if (showDetail) {
                model.addAttribute("targetPath", targetPath);
                model.addAttribute("totalFiles", files != null ? files.length : 0);
                model.addAttribute("successCount", 0);
                model.addAttribute("failCount", files != null ? files.length : 0);
                model.addAttribute("successFiles", new ArrayList<>());
                model.addAttribute("failedFiles", new ArrayList<>());
                model.addAttribute("error", "上传文件时发生错误: " + e.getMessage());
                
                // 添加简化模板表达式的属性
                model.addAttribute("hasTotalFiles", files != null && files.length > 0);
                model.addAttribute("hasSuccessFiles", false);
                model.addAttribute("hasFailedFiles", files != null && files.length > 0);
                model.addAttribute("allSuccess", false);
                
                // 设置默认的成功率和失败率
                model.addAttribute("successRate", "0%");
                model.addAttribute("successRateWidth", "0%");
                model.addAttribute("failRateWidth", files != null && files.length > 0 ? "100%" : "0%");
                
                return "file/upload-result";
            }
            redirectAttributes.addFlashAttribute("error", "上传文件时发生错误: " + e.getMessage());
        }

        // 重定向到目录浏览页面
        return "redirect:/file/browse?path=" + URLEncoder.encode(targetPath, StandardCharsets.UTF_8);
    }

    /**
     * REST API - 文件上传（支持多文件）
     * 
     * @param files 上传的文件数组
     * @param targetPath 目标路径
     * @param overwrite 是否覆盖同名文件
     * @param description 文件描述
     * @param uploader 上传者
     * @return 上传响应
     */
    @PostMapping("/api/upload")
    @ResponseBody
    public ResponseEntity<MultiFileUploadResponse> uploadFilesApi(
            @RequestParam("file") MultipartFile[] files,
            @RequestParam("targetPath") String targetPath,
            @RequestParam(value = "overwrite", defaultValue = "false") Boolean overwrite,
            @RequestParam(value = "description", required = false) String description,
            @RequestParam(value = "uploader", required = false) String uploader) {
        
        try {
            // 验证文件数组
            if (files == null || files.length == 0) {
                MultiFileUploadResponse errorResponse = new MultiFileUploadResponse();
                errorResponse.setSuccess(false);
                errorResponse.setMessage("请选择要上传的文件");
                return ResponseEntity.badRequest().body(errorResponse);
            }
            
            // 检查是否有空文件
            for (MultipartFile file : files) {
                if (file.isEmpty()) {
                    MultiFileUploadResponse errorResponse = new MultiFileUploadResponse();
                    errorResponse.setSuccess(false);
                    errorResponse.setMessage("检测到空文件，请重新选择");
                    return ResponseEntity.badRequest().body(errorResponse);
                }
            }
            
            // 创建上传请求对象
            FileUploadRequest request = new FileUploadRequest();
            request.setTargetPath(targetPath);
            request.setOverwrite(overwrite);
            request.setDescription(description);
            request.setUploader(uploader);

            // 执行多文件上传
            List<FileUploadResponse> responses = fileService.uploadFiles(files, request);
            
            // 构建多文件上传响应
            MultiFileUploadResponse multiResponse = new MultiFileUploadResponse();
            multiResponse.setResults(responses);
            
            // 统计结果
            long successCount = responses.stream().mapToLong(r -> r.getSuccess() ? 1 : 0).sum();
            long failCount = responses.size() - successCount;
            
            multiResponse.setTotalFiles(responses.size());
            multiResponse.setSuccessCount((int) successCount);
            multiResponse.setFailCount((int) failCount);
            
            if (successCount == responses.size()) {
                multiResponse.setSuccess(true);
                multiResponse.setMessage(String.format("成功上传 %d 个文件", successCount));
                return ResponseEntity.ok(multiResponse);
            } else if (successCount > 0) {
                multiResponse.setSuccess(true);
                multiResponse.setMessage(String.format("部分成功: 成功 %d 个，失败 %d 个", successCount, failCount));
                return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT).body(multiResponse);
            } else {
                multiResponse.setSuccess(false);
                multiResponse.setMessage(String.format("全部失败: %d 个文件上传失败", failCount));
                return ResponseEntity.badRequest().body(multiResponse);
            }

        } catch (Exception e) {
            MultiFileUploadResponse errorResponse = new MultiFileUploadResponse();
            errorResponse.setSuccess(false);
            errorResponse.setMessage("上传文件时发生错误: " + e.getMessage());
            errorResponse.setTotalFiles(files != null ? files.length : 0);
            errorResponse.setSuccessCount(0);
            errorResponse.setFailCount(files != null ? files.length : 0);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }

    /**
     * 文件下载
     * 
     * @param filePath 文件路径
     * @param inline 是否内联显示（默认为附件下载）
     * @return 文件响应
     */
    @GetMapping("/download")
    public ResponseEntity<Resource> downloadFile(
            @RequestParam("path") String filePath,
            @RequestParam(value = "inline", defaultValue = "false") Boolean inline) {
        
        try {
            // 检查路径安全性
            if (!fileService.isPathSafe(filePath)) {
                return ResponseEntity.badRequest().build();
            }

            // 获取文件资源
            Resource resource = fileService.downloadFile(filePath);
            
            // 获取文件名
            String fileName = resource.getFilename();
            if (fileName == null) {
                fileName = "download";
            }

            // 获取文件类型
            String contentType = fileService.getContentType(filePath);

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType(contentType));
            
            if (inline) {
                // 内联显示（在浏览器中打开）
                headers.setContentDisposition(
                    org.springframework.http.ContentDisposition.inline()
                        .filename(fileName, StandardCharsets.UTF_8)
                        .build()
                );
            } else {
                // 附件下载
                headers.setContentDisposition(
                    org.springframework.http.ContentDisposition.attachment()
                        .filename(fileName, StandardCharsets.UTF_8)
                        .build()
                );
            }

            return ResponseEntity.ok()
                .headers(headers)
                .body(resource);

        } catch (IOException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 删除文件
     * 
     * @param filePath 文件路径
     * @param redirectAttributes 重定向属性
     * @return 重定向到目录浏览页面
     */
    @PostMapping("/delete")
    public String deleteFile(
            @RequestParam("filePath") String filePath,
            RedirectAttributes redirectAttributes) {
        
        try {
            // 获取父目录路径
            java.io.File file = new java.io.File(filePath);
            String parentPath = file.getParent();
            
            // 删除文件
            boolean success = fileService.deleteFile(filePath);
            
            if (success) {
                redirectAttributes.addFlashAttribute("success", "文件删除成功");
            } else {
                redirectAttributes.addFlashAttribute("error", "文件删除失败");
            }
            
            // 重定向到父目录
            if (parentPath != null) {
                return "redirect:/file/browse?path=" + URLEncoder.encode(parentPath, StandardCharsets.UTF_8);
            } else {
                return "redirect:/file/";
            }
            
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("error", "删除文件时发生错误: " + e.getMessage());
            return "redirect:/file/";
        }
    }

    /**
     * REST API - 删除文件
     * 
     * @param filePath 文件路径
     * @return 删除结果
     */
    @DeleteMapping("/api/delete")
    @ResponseBody
    public ResponseEntity<String> deleteFileApi(@RequestParam("filePath") String filePath) {
        try {
            boolean success = fileService.deleteFile(filePath);
            
            if (success) {
                return ResponseEntity.ok("文件删除成功");
            } else {
                return ResponseEntity.badRequest().body("文件删除失败");
            }
            
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("删除文件时发生错误: " + e.getMessage());
        }
    }

    /**
     * 创建目录
     * 
     * @param parentPath 父目录路径
     * @param dirName 新目录名称
     * @param redirectAttributes 重定向属性
     * @return 重定向到目录浏览页面
     */
    @PostMapping("/mkdir")
    public String createDirectory(
            @RequestParam("parentPath") String parentPath,
            @RequestParam("dirName") String dirName,
            RedirectAttributes redirectAttributes) {
        
        try {
            // 构建新目录路径
            java.nio.file.Path newDirPath = java.nio.file.Paths.get(parentPath, dirName);
            String newDirPathStr = newDirPath.toString();
            
            // 创建目录
            boolean success = fileService.createDirectory(newDirPathStr);
            
            if (success) {
                redirectAttributes.addFlashAttribute("success", "目录创建成功");
            } else {
                redirectAttributes.addFlashAttribute("error", "目录创建失败");
            }
            
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("error", "创建目录时发生错误: " + e.getMessage());
        }
        
        // 重定向到父目录
        return "redirect:/file/browse?path=" + URLEncoder.encode(parentPath, StandardCharsets.UTF_8);
    }

    /**
     * REST API - 创建目录
     * 
     * @param parentPath 父目录路径
     * @param dirName 新目录名称
     * @return 创建结果
     */
    @PostMapping("/api/mkdir")
    @ResponseBody
    public ResponseEntity<String> createDirectoryApi(
            @RequestParam("parentPath") String parentPath,
            @RequestParam("dirName") String dirName) {
        
        try {
            // 构建新目录路径
            java.nio.file.Path newDirPath = java.nio.file.Paths.get(parentPath, dirName);
            String newDirPathStr = newDirPath.toString();
            
            // 创建目录
            boolean success = fileService.createDirectory(newDirPathStr);
            
            if (success) {
                return ResponseEntity.ok("目录创建成功");
            } else {
                return ResponseEntity.badRequest().body("目录创建失败");
            }
            
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("创建目录时发生错误: " + e.getMessage());
        }
    }

    /**
     * 重命名文件或目录
     * 
     * @param oldPath 原文件路径
     * @param newName 新文件名
     * @param redirectAttributes 重定向属性
     * @return 重定向到目录浏览页面
     */
    @PostMapping("/rename")
    public String renameFile(
            @RequestParam("oldPath") String oldPath,
            @RequestParam("newName") String newName,
            RedirectAttributes redirectAttributes) {
        
        try {
            // 重命名文件
            boolean success = fileService.renameFile(oldPath, newName);
            
            if (success) {
                redirectAttributes.addFlashAttribute("success", "文件重命名成功");
            } else {
                redirectAttributes.addFlashAttribute("error", "文件重命名失败");
            }
            
            // 获取父目录路径用于重定向
            java.io.File file = new java.io.File(oldPath);
            String parentPath = file.getParent();
            
            // 重定向到父目录
            if (parentPath != null) {
                return "redirect:/file/browse?path=" + URLEncoder.encode(parentPath, StandardCharsets.UTF_8);
            } else {
                return "redirect:/file/";
            }
            
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("error", "重命名文件时发生错误: " + e.getMessage());
            return "redirect:/file/";
        }
    }

    /**
     * REST API - 重命名文件或目录
     * 
     * @param oldPath 原文件路径
     * @param newName 新文件名
     * @return 重命名结果
     */
    @PostMapping("/api/rename")
    @ResponseBody
    public ResponseEntity<String> renameFileApi(
            @RequestParam("oldPath") String oldPath,
            @RequestParam("newName") String newName) {
        
        try {
            boolean success = fileService.renameFile(oldPath, newName);
            
            if (success) {
                return ResponseEntity.ok("文件重命名成功");
            } else {
                return ResponseEntity.badRequest().body("文件重命名失败");
            }
            
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("重命名文件时发生错误: " + e.getMessage());
        }
    }

    // ================ 图片预览功能 ================

    /**
     * 图片预览接口
     * 
     * @param filePath 图片文件路径
     * @return 图片文件响应
     */
    @GetMapping("/preview/image")
    public ResponseEntity<Resource> previewImage(@RequestParam("path") String filePath) {
        try {
            // 检查路径安全性
            if (!fileService.isPathSafe(filePath)) {
                return ResponseEntity.badRequest().build();
            }

            // 检查是否为图片文件
            if (!fileService.isImageFile(filePath)) {
                return ResponseEntity.badRequest().build();
            }

            // 获取图片资源
            Resource resource = fileService.downloadFile(filePath);
            
            // 获取文件名和类型
            String fileName = resource.getFilename();
            String contentType = fileService.getContentType(filePath);

            // 设置响应头（内联显示）
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType(contentType));
            headers.setContentDisposition(
                org.springframework.http.ContentDisposition.inline()
                    .filename(fileName, StandardCharsets.UTF_8)
                    .build()
            );
            
            // 添加缓存头
            headers.setCacheControl("max-age=3600"); // 1小时缓存

            return ResponseEntity.ok()
                .headers(headers)
                .body(resource);

        } catch (IOException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 视频预览接口
     * 
     * @param filePath 视频文件路径
     * @return 视频文件响应
     */
    @GetMapping("/preview/video")
    public ResponseEntity<Resource> previewVideo(@RequestParam("path") String filePath) {
        try {
            // 检查路径安全性
            if (!fileService.isPathSafe(filePath)) {
                return ResponseEntity.badRequest().build();
            }

            // 检查是否为视频文件
            if (!fileService.isVideoFile(filePath)) {
                return ResponseEntity.badRequest().build();
            }

            // 获取视频资源
            Resource resource = fileService.downloadFile(filePath);
            
            // 获取文件名和类型
            String fileName = resource.getFilename();
            String contentType = fileService.getContentType(filePath);

            // 设置响应头（内联显示）
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType(contentType));
            headers.setContentDisposition(
                org.springframework.http.ContentDisposition.inline()
                    .filename(fileName, StandardCharsets.UTF_8)
                    .build()
            );
            
            // 添加缓存头
            headers.setCacheControl("max-age=3600"); // 1小时缓存

            return ResponseEntity.ok()
                .headers(headers)
                .body(resource);

        } catch (IOException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 图片缩略图接口
     * 
     * @param filePath 图片文件路径
     * @param width 缩略图宽度（可选）
     * @param height 缩略图高度（可选）
     * @return 缩略图响应
     */
    @GetMapping("/preview/thumbnail")
    public ResponseEntity<Resource> previewThumbnail(
            @RequestParam("path") String filePath,
            @RequestParam(value = "width", defaultValue = "300") Integer width,
            @RequestParam(value = "height", defaultValue = "300") Integer height) {
        
        try {
            // 检查路径安全性
            if (!fileService.isPathSafe(filePath)) {
                return ResponseEntity.badRequest().build();
            }

            // 检查是否为图片文件
            if (!fileService.isImageFile(filePath)) {
                return ResponseEntity.badRequest().build();
            }

            // 限制缩略图尺寸
            width = Math.min(Math.max(width, 50), 800);
            height = Math.min(Math.max(height, 50), 800);

            // 生成缩略图
            Resource thumbnailResource = fileService.generateThumbnail(filePath, width, height);
            
            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_JPEG); // 缩略图使用JPEG格式
            headers.setContentDisposition(
                org.springframework.http.ContentDisposition.inline()
                    .filename("thumbnail.jpg", StandardCharsets.UTF_8)
                    .build()
            );
            
            // 添加缓存头
            headers.setCacheControl("max-age=7200"); // 2小时缓存

            return ResponseEntity.ok()
                .headers(headers)
                .body(thumbnailResource);

        } catch (IOException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 获取图片信息接口
     * 
     * @param filePath 图片文件路径
     * @return 图片信息
     */
    @GetMapping("/api/image-info")
    @ResponseBody
    public ResponseEntity<java.util.Map<String, Object>> getImageInfo(@RequestParam("path") String filePath) {
        try {
            // 检查路径安全性
            if (!fileService.isPathSafe(filePath)) {
                return ResponseEntity.badRequest().build();
            }

            // 检查是否为图片文件
            if (!fileService.isImageFile(filePath)) {
                return ResponseEntity.badRequest().build();
            }

            // 获取图片信息
            java.util.Map<String, Object> imageInfo = fileService.getImageInfo(filePath);
            
            return ResponseEntity.ok(imageInfo);

        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 生成访问首页的二维码
     * 
     * @param request HTTP请求对象
     * @return 二维码图片响应
     */
    @GetMapping("/qrcode")
    public ResponseEntity<byte[]> generateQRCode(HttpServletRequest request) {
        try {
            // 获取服务器地址和端口
            String scheme = request.getScheme();
            String serverName = request.getServerName();
            int serverPort = request.getServerPort();
            String contextPath = request.getContextPath()+"/file";
            
            // 构建首页URL
            String url;
            if (serverPort == 80 || serverPort == 443) {
                url = String.format("%s://%s%s/", scheme, serverName, contextPath);
            } else {
                url = String.format("%s://%s:%d%s/", scheme, serverName, serverPort, contextPath);
            }
            
            // 生成二维码
            byte[] qrCodeImage = generateQRCodeImage(url, 300, 300);
            
            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_PNG);
            headers.setContentDisposition(
                org.springframework.http.ContentDisposition.inline()
                    .filename("qrcode.png", StandardCharsets.UTF_8)
                    .build()
            );
            
            return ResponseEntity.ok()
                .headers(headers)
                .body(qrCodeImage);
                
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    /**
     * 生成二维码图片
     * 
     * @param text 二维码内容
     * @param width 宽度
     * @param height 高度
     * @return 二维码图片字节数组
     * @throws WriterException
     * @throws IOException
     */
    private byte[] generateQRCodeImage(String text, int width, int height) throws WriterException, IOException {
        // 设置二维码参数
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.MARGIN, 1);
        
        // 生成二维码矩阵
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
        
        // 转换为BufferedImage
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        
        // 转换为字节数组
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "PNG", byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();
    }

    /**
     * 全局异常处理器
     * 
     * @param ex 异常对象
     * @param request HTTP请求对象
     * @param model 模型对象
     * @return 错误页面
     */
    @ExceptionHandler(Exception.class)
    public String handleException(Exception ex, HttpServletRequest request, Model model) {
        // 记录错误信息
        System.err.println("Controller error in " + request.getRequestURI() + ": " + ex.getMessage());
        ex.printStackTrace();
        
        // 设置错误信息
        model.addAttribute("error", "系统错误: " + ex.getMessage());
        model.addAttribute("currentPath", request.getParameter("path") != null ? request.getParameter("path") : "");
        model.addAttribute("response", null);
        model.addAttribute("fileService", fileService);
        
        // 如果是browse请求，返回browse页面
        if (request.getRequestURI().contains("/browse")) {
            return "browse";
        }
        
        return "error";
    }
}